<html id="data-tutorial" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Introduction to Databinding</title>
</head>

<body>

<h1>Introduction to Databinding</h1>
<h2>Introduction</h2>


<p>We shall be examining how to interact with data in LZX.</p>

<a name="datapaths"></a>
<h2>The Basics</h2>

<p>As far as importing data into an LZX app is concerned, we always work in XML. The XML declaration is not required, but a single root XML node is. Data is represented by the <tagname>dataset</tagname> element.</p>

<example class="code" title="Datasets">
&lt;canvas height="80" width="500" &gt;
  &lt;dataset name="myData"&gt;
    &lt;myXML&gt;
      &lt;person show="simpsons"&gt;
        &lt;firstName&gt;Homer&lt;/firstName&gt;
        &lt;lastName&gt;Simpson&lt;/lastName&gt;
      &lt;/person&gt;
      &lt;person show="simpsons"&gt;
        &lt;firstName&gt;Marge&lt;/firstName&gt;
        &lt;lastName&gt;Simpson&lt;/lastName&gt;
      &lt;/person&gt;
      &lt;person show="simpsons"&gt;
        &lt;firstName&gt;Montgomery&lt;/firstName&gt;
        &lt;lastName&gt;Burns&lt;/lastName&gt;
      &lt;/person&gt;
    &lt;/myXML&gt;
  &lt;/dataset&gt;
  
  &lt;text datapath="myData:/myXML[1]/person[1]/firstName[1]/text()"/&gt;
&lt;/canvas&gt;
</example>

<p>In the above example, the single root element is myXML. The <attribute>datapath</attribute> attribute of the <tagname>text</tagname> tag binds it to the data.</p>

<p>Datapaths use XPath attributes to navigate through the XML data. So the name of the dataset to use goes before the colon <code>myData:</code>, followed by the nodes, separated by forward slashes (/). The square brackets provide a (one-based) space to enter which sibling node we want. [1] is implied, so the above example could be rewritten without any "[1]"s.</p>

<p>In plain English, the above example says: "get me the text from the first firstName node, of the first person node of the first (and of course, only) myXML node." The text() method call returns that nodes text.</p>

<p>To get Marge's name, we could rewrite the <tagname>text</tagname> tag as follows:</p>

<pre class="code">
&lt;text datapath="myData:/myXML/person[2]/firstName/text()" /&gt; 
</pre>

<p>(Note that I've omitted the "[1]"s as they are implied. To get the "show" attribute of Montgomery, we could write:</p>

<pre class="code">
&lt;text datapath="myData:/myXML/person[3]/@show" /&gt; 
</pre>

<p>The <code>/text()</code> path segment is unnecessary with the
<attribute>datapath</attribute> attribute.</p>


<p>So far we've used the <tagname>text</tagname> tag in conjunction with a single datapath. If we wanted to present tabular information, this would mean each text element would need its own datapath, and would be cumbersome and difficult to write. Instead let's make a quick table, by giving a <tagname>view</tagname> a datapath:</p>

<example class="code" title="Assigning a datapath to a view">
&lt;canvas height="80" width="500"&gt;
  &lt;dataset name="myData"&gt;
    &lt;myXML&gt;
      &lt;person show="simpsons"&gt;
        &lt;firstName&gt;Homer&lt;/firstName&gt;
        &lt;lastName&gt;Simpson&lt;/lastName&gt;
      &lt;/person&gt;
      &lt;person show="simpsons"&gt;
        &lt;firstName&gt;Marge&lt;/firstName&gt;
        &lt;lastName&gt;Simpson&lt;/lastName&gt;
      &lt;/person&gt;
      &lt;person show="simpsons"&gt;
        &lt;firstName&gt;Montgomery&lt;/firstName&gt;
        &lt;lastName&gt;Burns&lt;/lastName&gt;
      &lt;/person&gt;
    &lt;/myXML&gt;
  &lt;/dataset&gt;

  &lt;view name="rowOfData" <em>datapath="myData:/myXML[1]/person[1]"</em>&gt;
    &lt;simplelayout axis="x" /&gt;
    &lt;text <em>datapath="firstName/text()"</em> /&gt; 
    &lt;text <em>datapath="lastName/text()"</em> /&gt; 
    &lt;text <em>datapath="@show"</em> /&gt;
  &lt;/view&gt;
&lt;/canvas&gt;
</example>

<p>The datapath of the entire <varname>rowOfData</varname> view has now become Homer's <varname>person</varname> node. The child elements of <varname>rowOfData</varname> inherit this, so their datapaths can be referenced relatively.</p>

<h3>Multiple rows of data</h3>

<p>In the above example we used a single <varname>rowOfData</varname> node. Next, we shall use a range of nodes:</p>

<example class="code" title="Range of nodes">
&lt;canvas height="80" width="500" &gt;
  &lt;dataset name="myData"&gt;
    &lt;myXML&gt;
        &lt;person show="simpsons"&gt;
          &lt;firstName&gt;Homer&lt;/firstName&gt;
          &lt;lastName&gt;Simpson&lt;/lastName&gt;
        &lt;/person&gt;
        &lt;person show="simpsons"&gt;
          &lt;firstName&gt;Marge&lt;/firstName&gt;
          &lt;lastName&gt;Simpson&lt;/lastName&gt;
        &lt;/person&gt;
        &lt;person show="simpsons"&gt;
          &lt;firstName&gt;Montgomery&lt;/firstName&gt;
          &lt;lastName&gt;Burns&lt;/lastName&gt;
        &lt;/person&gt;
      &lt;/myXML&gt;
  &lt;/dataset&gt;

  &lt;view name="myTable"&gt;
    &lt;simplelayout axis="y" /&gt;
    &lt;view name="rowOfData" datapath="myData:/myXML[1]/person"&gt;
      &lt;simplelayout axis="x" /&gt;
      &lt;text datapath="firstName/text()" /&gt; 
      &lt;text datapath="lastName/text()" /&gt; 
      &lt;text datapath="@show" /&gt;
    &lt;/view&gt;
  &lt;/view&gt;
&lt;/canvas&gt;
</example>

<p>Whichever tag contains the <attribute>datapath</attribute> attribute will get repeated as often as is necessary.</p>

<!--p>There are five ways to specify  nodes:</p>

<!-
<table border="0" cellspacing="0" cellpadding="4" width="100%">
    <tr bgcolor="#DEE1F5">
        <td><span class="regular"><b>Example</b></span></td>
        <td><img src="./img/spacer.gif" width="10" height="1" alt="" border="0"/></td>
        <td><span class="regular"><b>Meaning</b></span></td>
        <td><img src="./img/spacer.gif" width="10" height="1" alt="" border="0"/></td>
        <td><span class="regular"><b>In this case</b></span></td>
    </tr>
    <tr valign="top">
        <td><pre class="code">myData:/myXML[1]/person<span class="redText">[1]</span></pre>
        </td>
        <td></td>
        <td><span class="regular">Just the first <i>person</i> node.</span></td>
        <td></td>
        <td><span class="regular">Homer</span></td>
    </tr>
    <tr valign="top">
        <td><pre class="code">myData:/myXML[1]/person</pre>
        </td>
        <td></td>
        <td><span class="regular">All the childnodes</span></td>
        <td></td>
        <td><span class="regular">Homer, Marge, Montgomery</span></td>
    </tr>
    <tr valign="top">
        <td><pre class="code">myData:/myXML[1]/person<span class="redText">[2-3]</span></pre>
        </td>
        <td></td>
        <td><span class="regular">Childnodes 2 to 3 inclusive</span></td>
        <td></td>
        <td><span class="regular">Marge, Montgomery</span></td>
    </tr>
    <tr valign="top">
        <td><pre class="code">myData:/myXML[1]/person<span class="redText">[2-]</span></pre>
        </td>
        <td></td>
        <td><span class="regular">Childnodes 2 and onwards</span></td>
        <td></td>
        <td><span class="regular">Marge, Montgomery</span></td>
    </tr>
    <tr valign="top">
        <td><pre class="code">myData:/myXML[1]/person<span class="redText">[-2]</span></pre>
        </td>
        <td></td>
        <td><span class="regular">Childnodes up to and including 2</span></td>
        <td></td>
        <td><span class="regular">Homer, Marge</span></td>
    </tr>
</table>
-->

<p>Remember that datapaths bind themselves to a view, so if the data changes, so will the view. We shall come to that a little later.</p>


<h2><a name="including"/>Ways to include data</h2>

<p>So far we've been using embedded data; i.e. XML that is written into the document. This is fine for very small amounts of static data, but there are other methods better suited to larger (or dynamic) data.</p>
 
<table>
  <tr>
    <th>How is it included?</th>
    <th>When is it loaded?</th>
    <th>Syntax</th>
  </tr>
  <tr>
    <td><a href="#embedded">Embedded</a></td>
    <td>Compile-time</td>
    <td>
<example class="code" extract="false">
&lt;dataset name="myData"&gt;
  &lt;myXML&gt;
     &lt;!-- ... other XML tags ... --&gt;
  &lt;/myXML&gt;
&lt;/dataset&gt;
</example>
    </td>
  </tr>
  <tr>
    <td><a href="#included">Included</a></td>
    <td>Compile-time</td>
    <td>
<pre>
&lt;dataset name="myData" src="myXMLDoc.xml"/&gt;
</pre>
    </td>
  </tr>
  <tr>
    <td><a href="#http">HTTP data</a></td>
    <td>Runtime</td>
        <td>
<pre>
&lt;dataset name="myData" autorequest="true" 
         type="http" src="myXMLDoc.xml" /&gt;
</pre>
    </td>
  </tr>    
</table>


<h3><a name="embedded"/>Embedded Data</h3>

<p>Embedded data is XML between the <tagname>dataset</tagname> tags. When the OpenLaszlo Server compiles the application, the data is bound into it. The data can still be changed after the application runs. Included data is static.</p>


<h3><a name="included"/>Included Data</h3>
<p>Included data is essentially the same as embedded data, except that the XML itself is kept in a separate file. The size of the initial download will be the same as with embedded data.</p>

<p>It is locally referenced via the filesystem, so it can be placed in other directories. Included data is static.</p>


<h3><a name="http"/>HTTP Data</h3>
<p>Remote data goes over HTTP, which means it can (but doesn't have to) be dynamic. If it is static, then the only difference between it and included or embedded data is that it is downloaded <i>after</i> the application loads. The <code>type="http"</code> attribute tells the LPS that this is an HTTP request. The requests can be either GET or POST. </p>

<p>There are several points at which the client requests for the data:</p>

<ul>
	<li>The client will request the data as soon as the app loads if the dataset's  <attribute>autorequest</attribute> attribute is true. </li>
	<li>The client will also request the data every time the querystring or base URL of the dataset changes (using the <method>setQueryString</method> or <method>setURL</method> respectively) methods of the <!-- TODO: add link to LZX ref -->LzHTTPDataset object.</li>
	<li>When the dataset's <method>doRequest</method> method gets called.</li>
</ul>

<p>In the table above, we referenced a file locally (myXMLDoc.xml), but we could have done it absolutely, or we could have hit a server-side (PHP, ASP, JSP or some CGI) that returned an XML document. We could add the query string to the <tagname>dataset</tagname> tag:</p>

<example class="code" extract="false">
&lt;dataset name="myData"
         <em>src="http://www.myServer.com/cgi-bin/myXMLDoc.cgi?return=addresses"</em>/&gt;
</example>

<p>The <code>type="http"</code> attribute gets implied when the <attribute>src</attribute> attribute contains "<code>http://</code>".</p>

<note>You do not have to worry about speed of the Flash Player's XML parser when using the LPS.</note>




<h2><a name="datapointers"/>Datapointers</h2>

<p>Datapaths are extremely handy, but if you need more control over the data, they can become cumbersome. Datapaths are actually extensions of datapointers, but are easier to learn, which is why we introduced them first. A datapointer is a pointer into the dataset, which can be moved around. It can only be in one place of the dataset at a time, but you can have multiple datapointers, each pointing to a different part of a dataset.</p>

<p>Datapointers are not bound to views like datapaths are, but they do have a place in the view hierarchy (i.e. they know about parents and children).</p>

<p>You would use a datapointer when you needed to operate on the data in some way. For example, using the same format of data as in the previous examples, say you wanted to find all the people who were in the South Park show:</p>


<example class="code" title="Manipulating datapointers">
&lt;canvas height="180" width="500" debug="true"&gt;
  &lt;dataset name="myData" src="../myShowData.xml" /&gt;
  
  &lt;datapointer xpath="myData:/" ondata="processData()"&gt;
    &lt;method name="processData"&gt;
      this.selectChild(2); 
      do {
        if (this.xpathQuery( '@show' ) == 'south park') {
            Debug.write(this.xpathQuery('firstName/text()'));
        }
      } while (this.selectNext()); 
    &lt;/method&gt;
  &lt;/datapointer&gt;
&lt;/canvas&gt;
</example>

<p>For brevity's sake, we are writing to the debugger, and we are including the data from a local file. <i>You can download that XML file at the top of this page</i>.</p>

<p>The first <code>selectNext(2)</code> method call selects first the <tagname link="false">myXML</tagname> node, then Homer's <tagname link="false">person</tagname> node. It selects two because of the depth argument "2" we pass it (otherwise it would default to 1.</p>

<p>The other <code>selectNext</code> method call returns <code>true</code> as long as an XML node was successfully selected (i.e. until there aren't any more). We exploit this by using it in a <code>do <i>&#x2026;</i> while</code> loop, so that the same iteration occurs for every <tagname>person</tagname> node.</p>

<p>We could also have given the <tagname>datapointer</tagname> <event>onerror</event> and <event>ontimeout</event> event handlers to capture any problems. </p>

</body>
</html>

<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2001-2004 Laszlo Systems, Inc.  All Rights Reserved.              *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
